/*
 * @Descripttion : popper 构造函数 (子集：dropdown, select, picker, color)
 * @Author       : liuzhifang
 * @Date         : 2022-02-18 15:58:06
 * @LastEditors  : QianFox Team
 * @LastEditTime : 2024-08-08 17:56:38
 */

import { _throttle } from './common/utils';

function Popper() {
    this.CHILDLIST = ['dropdown', 'select', 'picker', 'color']; // 关闭子集列表
    this.SCROLL = '.foxui-scroll-container'; // 监听此窗口内弹出框位置，并实时设置位置
    this.CLEAR_ICON = '.foxui-icon-cuowu-o'; // 所有输入框清空 icon 名
    this.xPlacement = ['bottom', 'left']; // 暂时没有用，主要是来设置小三角形的位置的
    this.top = '0'; // 暂时没有用 (弹出框不是内部节点，body直接子集时，需使用)
    this.left = '0'; // 暂时没有用 (弹出框不是内部节点，body直接子集时，需使用)
}

Popper.prototype = {
    _init() {
        this._clearMenusByClickBlank();
    },

    // 打开/关闭下拉弹出框
    _bindToggle() {
        let that = this;
        $(document).on('click', this.HANDLE, function (event) {
            event.stopPropagation();
            // 设置 data-trigger 为 click；或不设置（默认）为点击展开
            let trigger = $(this).attr('data-trigger');
            if (!trigger || trigger === 'click') {
                let $handle = $(this);
                let $menu = $handle.siblings(that.MENU);

                let isActive = $handle.is('.is-active');
                if (isActive) {
                    $handle.removeClass('is-active');
                    $menu.slideUp('fast');
                    // input 失去焦点(select)
                    $handle.find('input').blur();
                } else {
                    // 关闭所有的 menus
                    that._clearMenus();
                    // 设置弹出面板的位置(需放在显示前，否则会跳动);
                    that._setPosition(this);
                    // 显示
                    $handle.addClass('is-active');
                    $menu.slideDown('fast');
                    // input 获取焦点(select)
                    $handle.find('input').focus();
                }
            }
        });
    },

    // 绑定点击 选项 确定
    _bindConfirm() {
        let that = this;
        $(document).on('click', this.ITEM, function () {
            let $menu = $(this).closest(that.MENU);
            let $handle = $menu.siblings(that.HANDLE);

            $handle.removeClass('is-active');
            $menu.slideUp('fast');

            // 如果是 select 需填入 input 中
            let isSelect = $(this).is('.foxui-select-item');
            if (isSelect) {
                $handle.find('input').val($(this).text().trim());
                $handle.find('input').attr('data-id', $(this).attr('data-id'));
                // 添加当前项的 class
                $(this).siblings('.is-active').removeClass('is-active');
                $(this).addClass('is-active');
            }
        });
    },

    // 点击空白处，关闭所有 menus
    _clearMenusByClickBlank() {
        let that = this,
            x1 = 0,
            y1 = 0,
            x2 = 0,
            y2 = 0;
        // 鼠标按下时，记录鼠标位置
        $(document).mousedown(function (event) {
            x1 = event.clientX;
            y1 = event.clientY;
        });
        // 鼠标松开时，记录鼠标位置
        $(document).mouseup(function (event) {
            x2 = event.clientX;
            y2 = event.clientY;
        });
        // 判断鼠标是否移动，决定是否解发点击事件
        $(document).click(function () {
            if (!that._isDrag(x1, y1, x2, y2)) {
                that._clearMenus();
            }
        });
    },

    // 关闭所有 menus (foxui-***-handle；foxui-***-menu)
    _clearMenus() {
        this.CHILDLIST.forEach(item => {
            $('.foxui-' + item + '-handle').each(function () {
                let $handle = $(this);
                let $menu = $handle.siblings('.foxui-' + item + '-menu');

                let isActive = $(this).is('.is-active');
                if (isActive) {
                    $handle.removeClass('is-active');
                    $menu.slideUp('fast');
                }
            });
        });
    },

    /**
     * @description: 判断是否拖动了 (拖动为5px)
     * @param {*} x1
     * @param {*} y1
     * @param {*} x2
     * @param {*} y2
     * @return {*}
     * @Date: 2022-04-14 08:52:38
     */
    _isDrag(x1, y1, x2, y2) {
        if (Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) <= 5) {
            return false;
        }
        return true;
    },

    // 计算位置并设置
    _calcPosition(target) {
        // target -> HANDLE
        let clientHeight = document.documentElement.clientHeight; // 可视窗口高度
        let clientWidth = document.documentElement.clientWidth; // 可视窗口宽度

        let targetTop = target.getBoundingClientRect().top; // 目标元素的顶部距离
        let targetBottom = target.getBoundingClientRect().bottom; // 目标元素的底部距离
        let targetLeft = target.getBoundingClientRect().left; // 目标元素的左边距离
        let targetHeight = target.getBoundingClientRect().height; // 目标元素的高
        let targetWidth = target.getBoundingClientRect().width; // 目标元素的宽

        let $menu = $(target).siblings(this.MENU); // 弹出框是内部节点
        let menuHeight = $menu.height(); // 弹出框 popper 的高度
        let menuWidth = $menu.width(); // 弹出框 popper 的高度

        // 确定 上/下
        if (clientHeight - targetBottom - 48 > menuHeight) {
            this.top = parseInt(targetTop) + parseInt(targetHeight) + 'px';
            this.xPlacement[0] = 'bottom';
            $menu.css('top', targetHeight + 6 + 'px');
        } else {
            this.top = parseInt(targetTop) - parseInt(menuHeight) - 48 + 'px';
            this.xPlacement[0] = 'top';
            $menu.css('top', '-' + (parseInt(menuHeight) + 10) + 'px');
        }
        // 确定 左/右
        if (clientWidth - targetLeft - 24 > menuWidth) {
            this.left = parseInt(targetLeft) + 'px';
            this.xPlacement[1] = 'left';
            $menu.css('left', 0);
        } else {
            this.left =
                parseInt(targetLeft) - parseInt(menuWidth) - 24 + parseInt(targetWidth) + 'px';
            this.xPlacement[1] = 'right';
            $menu.css('left', targetWidth - menuWidth + 'px');
        }
        // 设置 x-placement 属性
        $menu.attr('x-placement', this.xPlacement.join('-'));
    },

    // 设置位置，及绑定窗口滚动及大小改变时，得新设置位置
    _setPosition(target) {
        // target -> HANDLE
        this._calcPosition(target);

        const that = this;
        $(window).on('scroll resize', function () {
            _throttle(that._calcPosition(target), 200);
        });

        // 监听 特定的容器
        $(this.SCROLL).on('scroll', function () {
            _throttle(that._calcPosition(target), 200);
        });
    },

    // 绑定清空输入框
    _bindClearInput() {
        let that = this;
        $(document).on('mouseover', this.CLEAR_HANDLE, function () {
            let $this = $(this),
                $clear = $this.find(that.CLEAR_ICON),
                $input = $this.find('input'),
                len = $input.val().length,
                isActive = $this.is('.is-active');

            if (!isActive && len > 0) {
                $clear.css('display', 'flex');
            }
        });

        $(document).on('mouseout', this.CLEAR_HANDLE, function () {
            let $this = $(this),
                $clear = $this.find(that.CLEAR_ICON);

            $clear.css('display', 'none');
        });

        $(document).on('click', this.CLEAR, function () {
            let $this = $(this),
                $handle = $this.closest(that.CLEAR_HANDLE);
            // 清空 input 的值
            $handle.find('input').val('');
            // 移除 多选 item 的 is-active 类
            $handle.siblings(that.MENU).find(that.ACTIVE).removeClass('is-active');
            // 隐藏清除 icon
            $this.css('display', 'none');
            return false;
        });
    },
};

let popper = new Popper();

export { Popper, popper };
